package com.crazecoder.flutter.iflyad;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.crazecoder.flutter.iflyad.utils.BannerUtil;
import com.crazecoder.flutter.iflyad.utils.InterstitialUtil;
import com.crazecoder.flutter.iflyad.utils.OAIDUtil;
import com.crazecoder.flutter.iflyad.utils.VideoAdUtil;
import com.crazecoder.flutter.iflyad.widget.SplashADFactory;
import com.iflytek.voiceads.IFLYAdSDK;
import com.iflytek.voiceads.config.AdKeys;

import java.util.ArrayList;
import java.util.List;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.common.StandardMessageCodec;


/**
 * FlutterIflyadPlugin
 */
public class FlutterIflyadPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private MethodChannel channel;
    private static Context context;
    private static Activity activity;
    private FlutterPluginBinding flutterPluginBinding;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        this.flutterPluginBinding = flutterPluginBinding;
    }

    // This static function is optional and equivalent to onAttachedToEngine. It supports the old
    // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
    // plugin registration via this function while apps migrate to use the new Android APIs
    // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
    //
    // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
    // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
    // depending on the user's project. onAttachedToEngine or registerWith must both be defined
    // in the same class.
    public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_iflyad");
        channel.setMethodCallHandler(new FlutterIflyadPlugin());
        activity = registrar.activity();
        context = registrar.context();
        SplashADFactory splashADFactory = new SplashADFactory(new StandardMessageCodec(), registrar.messenger());
        registrar.platformViewRegistry().registerViewFactory("splashADView", splashADFactory);
    }

    @TargetApi(Build.VERSION_CODES.M)
    private void checkAndRequestPermission() {
        List<String> lackedPermission = new ArrayList<String>();
        if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)) {
            lackedPermission.add(Manifest.permission.READ_PHONE_STATE);
        }

        if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
            lackedPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
            lackedPermission.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }

        if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.REQUEST_INSTALL_PACKAGES) == PackageManager.PERMISSION_GRANTED)) {
            lackedPermission.add(Manifest.permission.REQUEST_INSTALL_PACKAGES);
        }
        if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)) {
            lackedPermission.add(Manifest.permission.RECORD_AUDIO);
        }

        // 权限都已经有了，那么直接调用SDK
        if (lackedPermission.size() == 0) {
//      fetchSplashAD(this, container, skipView, appId, adId, splashADListener, 0);
        } else {
            // 请求所缺少的权限，在onRequestPermissionsResult中再看是否获得权限，如果获得权限就可以调用SDK，否则不要调用SDK。
            String[] requestPermissions = new String[lackedPermission.size()];
            lackedPermission.toArray(requestPermissions);
            ActivityCompat.requestPermissions(activity, requestPermissions, 1024);
        }
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if (call.method.equals("initAdSDK")) {
            checkAndRequestPermission();
            if (call.hasArgument("appId")) {
                String appId = call.argument("appId");
                initAdSDK(appId);
            }
            result.success(null);
        } else if (call.method.equals("showBannerAD")) {
            String adUnitId = call.argument("adUnitId").toString();
            BannerUtil.getInstance(activity).getBanner(adUnitId);
            BannerUtil.getInstance(activity).show(adUnitId);
            result.success(null);
        } else if (call.method.equals("disposeBannerAD")) {
            String adUnitId = call.argument("adUnitId").toString();
            BannerUtil.getInstance(activity).dispose(adUnitId);
            result.success(null);
        } else if (call.method.equals("showInterstitialAd")) {
            String adUnitId = call.argument("adUnitId").toString();
            InterstitialUtil.getInstance(activity).show(adUnitId);
            result.success(null);
        } else if (call.method.equals("showVideoAd")) {
            String adUnitId = call.argument("adUnitId").toString();
            VideoAdUtil.getInstance(activity).show(adUnitId);
            result.success(null);
        } else if (call.method.equals("disposeVideoAd")) {
//            String adUnitId = call.argument("adUnitId").toString();
            VideoAdUtil.getInstance(activity).dispose();
            result.success(null);
        } else {
            result.notImplemented();
        }
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }

    private void initAdSDK(String appid) {
        //设置全局参数，可根据需要进行设置，必须在初始化方法前设置
        IFLYAdSDK.setParameter(AdKeys.MAIN_PROCESS_NAME, appid);

        //进行SDK初始化
        IFLYAdSDK.init(context);
    }

    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
        activity = binding.getActivity();
        channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_iflyad");
        channel.setMethodCallHandler(this);
        context = flutterPluginBinding.getApplicationContext();
        SplashADFactory splashADFactory = new SplashADFactory(new StandardMessageCodec(), flutterPluginBinding.getBinaryMessenger());
        flutterPluginBinding.getPlatformViewRegistry().registerViewFactory("splashADView", splashADFactory);
        OAIDUtil.getInstance(context).init();
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {

    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {

    }

    @Override
    public void onDetachedFromActivity() {
        flutterPluginBinding = null;
    }
}
